
#include "chapter1_2.h"

using namespace std;



typedef struct CA_INFO
{
	int ca_id;
	int ecm_id;
	int emm_id;

}CA_INFO_S;

static const int MAX_KI = 5;
typedef struct CW_INFO
{
	char ki[MAX_KI];
	char cw[MAX_KI][16];
	int ki_save_index;

}CW_INFO_S;

typedef enum DD_FSM
{
	DD_FSM_CW_Getting,
	DD_FSM_MSK_Getting,
	DD_FSM_MSK_Done,

}DD_FSM_E;


class KMS_Manage
{

public :
	KMS_Manage() { memset(video_isma, 0, 12);	memset(audio_isma, 0, 12);};
	~KMS_Manage() {};
	bool fillEcm(char *ecm,int lens);
	bool cwGetting( );
	bool cwUse(char ki, char *cw);
	bool configIsma( short service_id);

private:
	char video_isma[12];
	char audio_isma[12];
	char ki_len;
	char iv_len;
	char ecm[1024];
	int ecm_len;
	CW_INFO_S cw_info;

};

bool KMS_Manage::fillEcm(char *pecm,int lens)
{
	if((lens == 0) || (lens > 1024))
		return false;

	memcpy(ecm, pecm, lens), ecm_len = lens;
	return true;
}

bool KMS_Manage::cwGetting( )
{
	//parse ecm

	//get_mtk

	//save cw

	return true;
}

bool KMS_Manage::cwUse(char ki,char *cw)
{
	//find ki-cw and return

	return true;
}

bool KMS_Manage::configIsma( short servid)
{
	//find ki-cw and return

	return true;
}

class Service
{	
public:
	short service_id;
	Service( );
	~Service() {};	

	Service * Add( short service_id);
	bool Remove( short service_id);
	bool isRegsitered(short service_id);

private:
	KMS_Manage kms;
	DD_FSM_E fsm;

	Service *now;
	Service *prev;
	Service *next;
};

Service::Service( )
{
	this->service_id = 0;
	this->now = 0;
	this->prev = 0;
	this->next = 0;

}


Service *Service::Add(short service_id)
{
	Service *pServ = new Service;

	pServ->service_id = service_id;
	//get ki.iv, isma
	//pServ->iv_len = 4, pServ->ki_len = 1,strcpy(pServ->audio_isma, "abcdefg"),strcpy(pServ->video_isma, "efghzxy");

	// add to list
	pServ->next = NULL;
	this->next = pServ;

#if 0
	else
	{
		Service *ptemp = now;

		now = pServ;
		now->next = NULL;
		next = NULL;
		now->prev = ptemp;
		prev = ptemp;
		ptemp->next = now;		
	}
#endif

	return pServ;
}

bool Service::Remove(short service_id)
{
	while(now != NULL)
	{	
		if(now->service_id == service_id)
		{
			Service *ptemp = NULL;

			if(now->prev != NULL)
			{
				now->prev->next = now->next;

				if(now->next != NULL)
					ptemp = now->next, now->next->prev = now->prev;
				else
					ptemp = now->prev;					
			}

			delete now;
			now = ptemp;
			this->prev = now->prev;
			this->next = now->next;

			return true;
		}
		else
		{
			now = now->prev;
		}
	}

	return false;

}




bool onCmmbMode2Fragment(char *data, int lens)
{
	extern Service tstDD;

	//tstDD.RegisterEcm(data, lens);
	//tstDD.DescrambleData(data, lens);
	
	return true;

}

Service *tstDD;

void test_dd()
{
	
	tstDD = new Service;

	tstDD = tstDD->Add(0x601);
	//tstDD.RemoveService(0x601);
	tstDD->Add(0x602);
	tstDD->Add(0x603);
	tstDD->Remove(0x603);

	tstDD->Remove(0x602);
	//tstDD.


	//list<Service*> servManageList;
	//Service *temp = new Service(0x608);

	//servManageList.push_back( temp);
	///servManageList.push_back( temp);

}